﻿namespace DeltaGroup.WheelOfJeopardy.ChallengeManager
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text.RegularExpressions;
    using System.Windows;
    using System.Xml.Serialization;

    using DeltaGroup.WheelOfJeopardy.GameManager;
    using DeltaGroup.WheelOfJeopardy.Model;

    public class ChallengeManager : IChallengeManager
    {
        #region Fields

        private static ChallengeManager _challengeManager;

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ChallengeManager"/> class.
        /// </summary>
        private ChallengeManager()
        {
        }

        #endregion Constructors

        #region Methods

        /// <summary>
        /// Gets the instance.
        /// </summary>
        /// <returns></returns>
        public static ChallengeManager GetInstance()
        {
            if (_challengeManager == null)
            {
                _challengeManager = new ChallengeManager();
            }
            return _challengeManager;
        }

        /// <summary>
        /// Gets the challenges.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <returns></returns>
        public ChallengeSet GetChallenges(string fileName)
        {
            return this.ReadChallengeSetFromFile(fileName);
        }

        /// <summary>
        /// Gets the game files.
        /// </summary>
        /// <returns></returns>
        public List<string> GetGameFiles()
        {
            string path = @"woj\config";
            List<string> fileNames = new List<string>();

            // matches a file that ends with an xml extension, but does not include the extension
            Regex fileRegex = new Regex(@"([^\\]*)(?=.xml)");

            foreach (string fileName in Directory.GetFileSystemEntries(path, "*.xml"))
            {
                fileNames.Add(fileRegex.Match(fileName).Value);
            }
            return fileNames;
        }

        /// <summary>
        /// Determines whether [is response correct] [the specified challenge].
        /// </summary>
        /// <param name="challenge">The challenge.</param>
        /// <param name="response">The response.</param>
        /// <returns>
        /// 	<c>true</c> if [is response correct] [the specified challenge]; otherwise, <c>false</c>.
        /// </returns>
        public bool IsResponseCorrect(DifficultyLevel level, Challenge challenge, string response)
        {
            ResponseInterpreter interpreter = new ResponseInterpreter(level);
            bool isCorrect = interpreter.EvaluateResponse(challenge, response);

            return isCorrect;
        }

        /// <summary>
        /// Reads the challenge set from file.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <returns></returns>
        public ChallengeSet ReadChallengeSetFromFile(string fileName)
        {
            ChallengeSet challengeSet = null;

            string filePath = @"woj\config";
            filePath += String.Format(@"\{0}.xml", fileName);

            using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
            {
                XmlSerializer challengeSerializer = new XmlSerializer(typeof(ChallengeSet));
                challengeSet = challengeSerializer.Deserialize(stream) as ChallengeSet;
            }

            return challengeSet;
        }

        /// <summary>
        /// Writes the challenge set to file.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="challengeSet">The challenge set.</param>
        public void WriteChallengeSetToFile(string fileName, ChallengeSet challengeSet)
        {
            XmlSerializer challengeSerializer = null;
            FileStream stream = null;

            string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            Directory.CreateDirectory(folderPath + @"\woj");
            folderPath += @"\woj";
            folderPath += String.Format(@"\{0}.xml", fileName);

            using (stream = new FileStream(folderPath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                challengeSerializer = new XmlSerializer(typeof(ChallengeSet));

                try
                {
                    challengeSerializer.Serialize(stream, challengeSet);
                }
                catch (InvalidOperationException)
                {
                    MessageBox.Show("Could not write to this file location, please choose another.");
                }
            }
        }

        #endregion Methods
    }
}